gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/libsrc/ringdows/ringmdiframewnd.cpp
/********************************************************************** // // // ########## ###### ######### # ###### # // ############# ########### ######### ######### ### // ######## # ### ## ############# ## ## ##### # #### // #### ## ## ### ### ### # # ##### ##### // # ### # # ## ## ## ## ### // ## ###### ## ## #### #### # # ## // ######### ### ## ### ####### ###### ## ## ### // ###### ## ###### ## ## #### # ## #### // ####### ## ###### ## ### ## ## ### ###### // ######### ## ###### ## ###### ### ## ### # ##### // ## ###### ####### ### #### ## ## ####### ######## ## #### // ## #### ### # ### ### ## ########## ###### ## #### // ## ## ## ######### #### # ## // # ### // ## // ### // ## // // // 临风程序界面类库 ringdows.lib //作者:临风 // //版本:1.0 // //声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到 // 你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在 // 修改的同时给作者一份同样的副本。 // 本类库不得用于任何商业用途,如确实需要,请与作者联系。 // //e-mail:ringphone@sina.com // //原文件名:ringmdiframewnd.cpp // //本文件说明:RingMDIFrameWnd类实现代码 // //类库功能:多文档窗口的封装 // **********************************************************************/ #define MAKE_SELF_LIB #include "ringdows.h" //extern ringFile rfc; //extern char cc[80]; RingMDIFrameWnd::RingMDIFrameWnd() { m_nChildid = 0; m_menuBar = NULL; m_windowInfo.hCursor = LoadCursor(NULL,IDC_ARROW); m_windowInfo.hIconBig = NULL; m_windowInfo.hIconSmall = NULL; m_windowInfo.lpszMenu = NULL; m_windowType = ITIS_MDIFRAME; } RingMDIFrameWnd::~RingMDIFrameWnd() { //delete m_client; } /***************************************************************** // //通知子窗口处理消息,如WM_SIZE等,子窗口可以跟随父窗口调整尺寸 // //额外的处理:需要先按上下左右顺序先通知DockSite,否则如果有自动调整 //尺寸的子窗口先于DockSite创建,因为DockSite尚未调整尺寸,则GetClientRect //返回不正确,导致所有子窗口处理完毕后该窗口尺寸不正确 // *****************************************************************/ void RingMDIFrameWnd::NotifyChild(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { RingWnd::NotifyChild(hWnd,uMsg,wParam,lParam); if(uMsg == WM_SIZE || uMsg == WM_DOCKSITESIZECHANGE) { if (wParam != SIZE_MINIMIZED) { RECT rc; GetClientRect(&rc); MoveWindow(m_client.Handle(), rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE); } } } void RingMDIFrameWnd::OnCreate(HWND hWnd) { CLIENTCREATESTRUCT ccs = {0}; RingWnd::OnCreate(hWnd); FindWindowMenu(&ccs); m_client.SetParentObj(this); ::ShowWindow(m_client.Create(&ccs),SW_SHOW); } void RingMDIFrameWnd::FindWindowMenu(LPCLIENTCREATESTRUCT lpccs) { HMENU hMenu = GetMenu(); int numItems = GetMenuItemCount(hMenu) - 2; if(numItems < 0) numItems = 0; lpccs->hWindowMenu = GetSubMenu(hMenu,numItems); numItems = GetMenuItemCount((HMENU)lpccs->hWindowMenu); lpccs->idFirstChild = GetMenuItemID((HMENU)lpccs->hWindowMenu,numItems-1) + 10; } HWND RingMDIFrameWnd::Create(LPCTSTR szTitle,LPCTSTR szClass, DWORD dwStyle,DWORD dwExStyle, int x,int y,int width,int height, HWND hParentWnd/*=NULL*/,HMENU hMenu/*=NULL*/, LPARAM lParam/*=0*/) { if(!Register(szClass, (HBRUSH)(COLOR_WINDOW + 1), m_windowInfo.lpszMenu, m_windowInfo.hIconBig, m_windowInfo.hCursor, m_windowInfo.hIconSmall)) return NULL; wsprintf(m_szChildClass,"%s_RingSDKMDIChild\0",szClass); Register(m_szChildClass, (HBRUSH)(COLOR_WINDOW + 1), NULL,//..m_windowInfo.lpszMenu, m_windowInfo.hIconBig, m_windowInfo.hCursor, m_windowInfo.hIconSmall, ITIS_MDICHILD); CreateEx(szTitle,szClass,dwStyle | WS_CLIPCHILDREN,dwExStyle,hParentWnd,hMenu, x,y,width,height,lParam); return m_hWnd; } BOOL RingMDIFrameWnd::CreateChild(LPCTSTR lpszTitle,RingWnd* child,BOOL bOpen/*=FALSE*/, DWORD dwStyle/*=0*/,LPARAM lParam/*=0*/, LPSTR szClass/*=NULL*/) { m_nChildid ++; MDICREATESTRUCT mcs; LPTSTR str = (LPTSTR)New(lstrlen(lpszTitle) + 8); if(str) { int nCmdShow = SW_SHOW; BOOL bMax = FALSE; if(GetCurrChildWnd(&bMax) && bMax) nCmdShow = SW_SHOWMAXIMIZED; if(bOpen) lstrcpy(str,lpszTitle); else wsprintf(str,"%s%d",lpszTitle,m_nChildid); if(szClass == NULL) mcs.szClass = m_szChildClass; else mcs.szClass = szClass; RINGWNDPARAM wndParam = {child,lParam}; mcs.szTitle = str; mcs.hOwner = GetInstance(); mcs.x = CW_USEDEFAULT; // x position mcs.y = CW_USEDEFAULT; // y position mcs.cx = CW_USEDEFAULT; // width mcs.cy = CW_USEDEFAULT; // height mcs.style = dwStyle;// & ~(WS_MAXIMIZE | WS_VISIBLE); // window style mcs.lParam = (LPARAM)&wndParam; // lparam HWND hwndChild = (HWND)SendMessage(m_client.Handle(),WM_MDICREATE,0,(LPARAM)&mcs); if(hwndChild) { ::ShowWindow(hwndChild,nCmdShow); SendMessage(m_client.Handle(),WM_MDIREFRESHMENU,0,0); ::SetFocus(hwndChild); } Del(str); return TRUE; } return FALSE; } RingMDIChildWnd* RingMDIFrameWnd::GetCurrChild(LPBOOL bMax/*=NULL*/) { HWND hwnd = (HWND)SendMessage(GetClient(),WM_MDIGETACTIVE,0,(LPARAM)bMax); if(hwnd) return (RingMDIChildWnd*)GetWindowPtr(hwnd); else return NULL; } HWND RingMDIFrameWnd::GetCurrChildWnd(LPBOOL bMax/*=NULL*/) { return (HWND)SendMessage(GetClient(),WM_MDIGETACTIVE,0,(LPARAM)bMax); } RingMDIChildWnd* RingMDIFrameWnd::GetMDIChild() { return (RingMDIChildWnd*)GetWindowPtr(m_client.GetChild()); } RingMDIChildWnd* RingMDIFrameWnd::GetNextMDIChild(RingMDIChildWnd* child) { if(child) return (RingMDIChildWnd*)GetWindowPtr(m_client.GetNextChild(child->Handle())); else return (RingMDIChildWnd*)GetWindowPtr(m_client.GetChild()); } void RingMDIFrameWnd::CascadeChild(UINT flag/*=0*/) { SendMessage(GetClient(),WM_MDICASCADE,0,0); } void RingMDIFrameWnd::TileChild(UINT flag/*=MDITILE_VERTICAL*/) { SendMessage(GetClient(),WM_MDITILE,flag,0); } void RingMDIFrameWnd::CloseChild(HWND hWnd/*=NULL*/) { if(hWnd == NULL) hWnd = GetCurrChildWnd(); SendMessage(GetClient(),WM_MDIDESTROY,(WPARAM)hWnd,0L); } void RingMDIFrameWnd::ActiveChild(HWND hWnd) { SendMessage(GetClient(),WM_MDIACTIVATE,(WPARAM)hWnd,0L); } void RingMDIFrameWnd::ArrangeIcon(UINT event) { SendMessage(GetClient(),WM_MDIICONARRANGE,0,0L); } void RingMDIFrameWnd::MaxChild(UINT event) { SendMessage(GetClient(),WM_MDIMAXIMIZE,SendMessage(GetClient(),WM_MDIGETACTIVE,0,0),0L); } void RingMDIFrameWnd::MinChild(UINT event) { RingMDIChildWnd *child = GetCurrChild(); if(child) child->Show(SW_MINIMIZE); } void RingMDIFrameWnd::RestoreChild(UINT event) { SendMessage(GetClient(),WM_MDIRESTORE,SendMessage(GetClient(),WM_MDIGETACTIVE,0,0),0L); } BOOL RingMDIFrameWnd::KeepChildActive() { HWND hwnd = GetClient(); if(hwnd) { HWND hwndChild = GetWindow(hwnd,GW_CHILD); if(hwndChild) { SendMessage(hwndChild,WM_CHILDACTIVATE,0,0); return TRUE; } } return FALSE; } /* BOOL RingMDIFrameWnd::IsChildMax() { HWND hwnd = (HWND)SendMessage(GetClient(),WM_MDIGETACTIVE,0,0); if(hwnd) return IsZoomed(hwnd); else return FALSE; } */ RingMenuBar* RingMDIFrameWnd::GetMenuBar() { if(m_menuBar)// && IsWindowPtr(m_menuBar)) return m_menuBar; else return NULL; /* HWND hwnd; RingBaseWnd* obj; if(m_dockSite) { for(int i=0;i<4;i++) if(m_dockSite[i]) { hwnd = m_dockSite[i]->GetChild(); while(hwnd) { obj = GetWindowPtr(hwnd); if(obj && obj->GetWindowType() == ITIS_MENUBAR) return (RingMenuBar*)obj; hwnd = m_dockSite[i]->GetNextChild(hwnd); } } } return NULL; */ } HWND RingMDIClient::Create(CLIENTCREATESTRUCT* lpccs) { m_nFirstChildid = lpccs->idFirstChild; m_parentMenu = (HMENU)lpccs->hWindowMenu; m_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,"MDICLIENT", NULL, WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MDIS_ALLCHILDSTYLES | WS_VSCROLL | WS_HSCROLL, 0,0,0,0, m_parent->Handle(), (HMENU)0xCAC, GetInstance(), (LPVOID)lpccs); if(m_hWnd) SubClassWindow(m_hWnd); //m_ID = 0xCAC; return m_hWnd; } LRESULT RingMDIClient::RingdowProc(HWND,RINGPARAMS param) { switch(param.uMsg) { case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_KEYDOWN: case WM_KEYUP: return SendMessage(m_parent->Handle(),param.uMsg,param.wParam,param.lParam); case WM_NCDESTROY: if(m_extWnd) *m_extWnd = NULL; CallWindowProc(m_DefProc,m_hWnd,param.uMsg,param.wParam,param.lParam); OnNcDestroy(); m_hWnd = NULL; return 0; //case WM_MDIMAXIMIZE: //case WM_MDIMIN //case WM_MDIRESTORE: case WM_MDICREATE: //case WM_MDIDESTROY: case WM_MDINEXT: case WM_MDIACTIVATE: { RingCoolMenu* rm = ((RingMDIFrameWnd*)m_parent)->GetCoolMenu(); if(m_parent->GetMenu() == NULL && rm) { LRESULT res = CallWindowProc(m_DefProc,m_hWnd,param.uMsg,param.wParam,param.lParam); RefreshMenu(rm,NULL);//(HWND)param.wParam); //if(param.uMsg == WM_MDINEXT) // UpdateMenuBar((HWND)param.lParam); //else UpdateMenuBar(NULL);//(HWND)param.wParam); return res; } break; } //case WM_MDISETMENU: // return DefaultProc(param); case WM_MDIREFRESHMENU: { LRESULT res = CallWindowProc(m_DefProc,m_hWnd,param.uMsg,param.wParam,param.lParam); RingCoolMenu* rm = ((RingMDIFrameWnd*)m_parent)->GetCoolMenu(); if(rm) { int cnt = rm->GetSubMenuCount(); while((--cnt) >= 0) { if(rm->SubMenu(cnt)->GetMenu() == m_parentMenu) { rm->SubMenu(cnt)->ReScan(); break; } } UpdateMenuBar(NULL); //int cnt = rm->GetItemCount(); //cnt -= 2; //if(cnt < 0) // cnt = 0; //rm->SubMenu(cnt)->ReScan(); } return res; } //*/ /*case WM_MDIDESTROY: case WM_MDIGETACTIVE: case WM_MDICREATE: case WM_MDIREFRESHMENU: { LRESULT res = CallWindowProc(m_DefProc,m_hWnd,param.uMsg,param.wParam,param.lParam); RingCoolMenu* rm = ((RingMDIFrameWnd*)m_parent)->GetCoolMenu(); if(rm) { int cnt = rm->GetItemCount(); cnt -= 2; if(cnt < 0) cnt = 0; rm->SubMenu(cnt)->ReScan(); } //DrawMenuBar(m_parent->Handle()); //*/ // return res; // } } return CallWindowProc(m_DefProc,m_hWnd,param.uMsg,param.wParam,param.lParam); } /************************************************************* // //更新父窗口菜单栏 // // 因为菜单栏把父窗口的菜单剥离下来,父窗口无菜单的情况下 // 当创建的子窗口超过10个,“窗口”菜单中的子窗口列表菜单 // 项将不会显示新创建的子窗口菜单项,但是第9个子窗口的菜单 // 项命令ID已绑定到新建子窗口,因此需要调用该函数使其表现 // 正常,即只需改变其菜单项的文字。 // // 需要调用本函数的情况: // 1、创建子窗口时(WM_MDICREATE),本函数自动判断是否超 // 过10个子窗口 // 2、子窗口通过选择菜单激活(WM_MDIACTIVATE) // 3、子窗口通过按键激活(子窗口的WM_ACTIVATE并且 // wParam参数为WA_CLICKACTIVE) // *************************************************************/ void RingMDIClient::RefreshMenu(RingCoolMenu* rm,HWND hChildWnd) { if(hChildWnd == NULL) hChildWnd = (HWND)SendMessage(m_hWnd,WM_MDIGETACTIVE,0,0); UINT id = hChildWnd?GetWindowLong(hChildWnd,GWL_ID):0; if(id - m_nFirstChildid == 8) { char txt[200],title[160]; MENUITEMINFO mi; memset(title,0,160); GetWindowText(hChildWnd,title,160); wsprintf(txt,"&9 %s\0",title); mi.cbSize = sizeof(MENUITEMINFO); mi.fMask = MIIM_TYPE | MIIM_STATE; mi.fType = MFT_STRING; mi.dwTypeData = txt; mi.cch = strlen(txt); mi.fState = MFS_CHECKED; SetMenuItemInfo(m_parentMenu,id,FALSE,&mi); mi.fMask = MIIM_DATA | MIIM_TYPE; GetMenuItemInfo(m_parentMenu,id,FALSE,&mi); mi.fType |= MFT_OWNERDRAW; SetMenuItemInfo(m_parentMenu,id,FALSE,&mi); } } void RingMDIClient::UpdateMenuBar(HWND hChildWnd) { if(hChildWnd == NULL) hChildWnd = (HWND)SendMessage(m_hWnd,WM_MDIGETACTIVE,0,0); BOOL bmax; if(hChildWnd == NULL) bmax = FALSE; else bmax = IsZoomed(hChildWnd); if(bmax != m_bChildMax) { m_bChildMax = bmax; RingMenuBar *bar = ((RingMDIFrameWnd*)m_parent)->GetMenuBar(); if(bar) bar->SetSysControlInfo(m_bChildMax); } }